﻿using System;
using System.Collections.Generic;
using Deployment.Data.Deploy.Steps.Tasks;
using System.Xml;
using Deployment.Data.Environment.Connection;
using Deployment.Data.SQL.Connections;

namespace Deployment.Data.SQL.Tasks
{
    public abstract class AbstractSQLTask : AbstractTask
    {

        private const string ELEMENT_CONNECTION = "Connection";
        private string _connection;

        public string Connection
        {
            get { return _connection; }
            set
            {
                if (_connection != value)
                {
                    _connection = value;
                    OnPropertyChanged("Connection");
                }
            }
        }

        #region AbstractTask overrides

        protected override void ReadElement(XmlReader reader)
        {
            while (true)
            {
                if (!reader.Read())
                    break;
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name.Equals(ELEMENT_CONNECTION, StringComparison.CurrentCultureIgnoreCase))
                    {
                        Connection = reader.ReadElementContentAsString();
                    }
                    else
                    {
                        readSubElement(reader);
                    }
                }
                else if (reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("Task"))
                {
                    break;
                }
            }
        }

        protected override void WriteElement(System.Xml.XmlWriter writer)
        {
            writer.WriteElementString(ELEMENT_CONNECTION, "", _connection);
            writeSubElements(writer);
        }

        protected override bool performTaskValidation(Environment.Environment executionEnvironment, out string message)
        {
            List<AbstractConnection> connections = executionEnvironment.getConnectionsByName(Connection);
            if (connections.Count == 0)
            {
                message = string.Format("No connection named [{0}] was found in environment [{1}]", Connection, executionEnvironment.Name);
                return false;
            }
            foreach (AbstractConnection con in connections)
            {
                if (!(con is AbstractSQLConnection))
                {
                    message = string.Format("Task [{0}].[{1}] requires a SQL connections!", Id, Description);
                    return false;
                }
            }
            return performSQLTaskValidation(executionEnvironment, out message);
        }

        protected override void performClone(ref AbstractTask copy)
        {
            AbstractSQLTask task = copy as AbstractSQLTask;
            if (task == null)
                throw new InvalidCastException("Task is not an AbstactSQLTask!");
            task.Connection = this.Connection;
            AbstractSQLTaskClone(task);
            copy = task;
        }

        #endregion
        


     

        protected abstract void readSubElement(XmlReader reader);

        protected abstract void writeSubElements(XmlWriter writer);

        protected abstract bool performSQLTaskValidation(Environment.Environment executionEvnironment, out string message);

        protected abstract void AbstractSQLTaskClone(AbstractSQLTask copy);

    }
}
